/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd;

import java.util.ArrayList;
import java.util.List;

import org.zhiqim.kernel.model.maps.HashMapSS;
import org.zhiqim.httpd.util.Scripts;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.httpd.validate.OneValidate;
import org.zhiqim.httpd.validate.TwoValidate;
import org.zhiqim.httpd.validate.Validate;

/**
 * 请求中的验证信息
 * 1.支持在Action/view中增加验证项: request.addValidate(new IsNotEmpty("field", "该字估不允许为空"));
 * 2.支持设置验证提交后，按钮设置成disabled，因此按钮尽可能使用button来提交，以保证disabled可用
 * 3.支持验证成功后，弹出确认信息，请设置confirm值
 * 
 * @version v1.0.0 @author zouzhigang 2016-7-18 新建与整理
 */
public abstract class HttpRequestValidate extends HttpHeaderInner implements HttpRequest
{
    private String confirm = null;           //form提交前确认信息，不为空白表示有效，生成if (confirm(""))此类代码
    private boolean isGray = true;          //form提交后按钮是否为灰色，默认变灰，防止多次提交
    private List<Validate> validateList;     //form表单字段验证列表
    
    /** 设置确认信息 */
    public void setValidateConfirm(String confirm)
    {
        this.confirm = confirm;
    }
    
    /** 使提交按钮变灰 */
    public void setValidateGray(boolean isGray)
    {
        this.isGray = isGray;
    }
    
    /** 获取验证列表 */
    public List<Validate> getValidateList()
    {
        return (validateList==null)?new ArrayList<Validate>():validateList;
    }
    
    /** 增加验证信息 */
    public void addValidate(Validate validate)
    {
        if (validateList == null)
            validateList = new ArrayList<>(5);
            
        validateList.add(validate);
    }
    
    /** 清除所有的验证信息 */
    public void clearValidate()
    {
        if (validateList != null)
            validateList.clear();
    }
    
    /** 检查验证信息 */
    public boolean chkValidate()
    {
        if (validateList == null)
            return true;
        
        for (Validate validate : validateList)
        {
            if (validate instanceof OneValidate)
            {
                OneValidate one = (OneValidate)validate;
                String value = getParameter(one.getField());
                if (!one.validate(value))
                {
                    setAlertMsg(one.getAlertMsg());
                    return false;
                }
            }
            else if (validate instanceof TwoValidate)
            {
                TwoValidate two = (TwoValidate)validate;
                String value1 = getParameter(two.getField());
                String value2 = getParameter(two.getField2());
                if (!two.validate(value1, value2))
                {
                    setAlertMsg(two.getAlertMsg());
                    return false;
                }
            }
        }
        return true;
    }
    
    /** 检查验证Script，无验证返回空，有则返回Script */
    public String chkValidateScript()
    {
        if (validateList == null)
            return _EMPTY_;
        else
            return getValidateScript();
    }
    
    /** 获取验证字符串 */
    public String getValidateScript()
    {
        StringBuilder strb = new StringBuilder();
        strb.append(Scripts.head());
        strb.append(Scripts.SCRIPT_HEAD_VALIDATE);
        
        //创建一个HashMap,利用HashMap不允许重复的约束,使得调用的函数唯一
        HashMapSS functionMap = new HashMapSS();
        if (!Validates.isEmpty(validateList))
        {
            for (Validate validate : validateList)
            {
                strb.append(validate.getScript());
                functionMap.put(validate.getName(), validate.getFunction());
            }
        }
        
        if (!Validates.isEmpty(confirm))
        {//增加确认提示
            strb.append(Scripts.getConfirm(confirm));
        }
        
        if (isGray)
        {// 使提交按钮变灰
            strb.append(Scripts.getGraySubmit(isFirefox()));
        }
        
        strb.append(Scripts.SCRIPT_TAIL_VALIDATE);
        
        //变灰和恢复两个函数
        strb.append(Scripts.setFormButtonGray());
        strb.append(Scripts.setFormButtonResume());
        
        //验证函数
        for (String function : functionMap.values())
        {
            strb.append(function);
        }
        
        if (strb.length() >= 4 && "\r\n\r\n".equals(strb.substring(strb.length() - 4)))
        {//去掉可能的最后是两个\r\n的一个\r\n
            strb.setLength(strb.length()-2);
        }
        
        strb.append(Scripts.tail());
        return strb.toString();
    }
    
    /** 获取验证提交脚本 */
    public String getValidateSubmitScript()
    {
        StringBuilder strb = new StringBuilder();
        strb.append(Scripts.head());
        strb.append(Scripts.SCRIPT_HEAD_SUBMIT);
        
        //创建一个HashMap,利用HashMap不允许重复的约束,使得调用的函数唯一
        HashMapSS functionMap = new HashMapSS();
        if (!Validates.isEmpty(validateList))
        {
            for (Validate validate : validateList)
            {
                strb.append(validate.getScript());
                functionMap.put(validate.getName(), validate.getFunction());
            }
        }
        
        if (Validates.isEmpty(confirm))
        {
            if (isGray)
            {// 使提交按钮变灰
                strb.append(Scripts.getGraySubmit(isFirefox()));
            }
            
            strb.append(_FOUR_).append("form.submit();").append(_BR_);
        }
        else
        {//增加确认提示
            strb.append(_FOUR_).append("Z.confirm(\"").append(confirm).append("\", function()").append(_BR_);
            strb.append(_FOUR_).append("{").append(_BR_);
            
            if (isGray)
            {
                if (!isFirefox())
                {//非火狐直接变灰
                    strb.append(_FOUR_).append(_FOUR_).append("setFormButtonGray(form);").append(_BR_);
                }
                else
                {//火狐检查是否有F && Z.onload，否则回退没办法恢复
                    strb.append(_FOUR_).append(_FOUR_).append("if (Z && Z.onload)").append(_BR_)
                        .append(_FOUR_).append(_FOUR_).append("{//firefox要求F && Z.onload时才支持提交变灰和回退恢复").append(_BR_).append(_BR_)
                        //变灰
                        .append(_FOUR_).append(_FOUR_).append(_FOUR_).append("setFormButtonGray(form);").append(_BR_)
                        //回退
                        .append(_FOUR_).append(_FOUR_).append(_FOUR_).append("Z.onload(function(form){setFormButtonResume(form);}, form);").append(_BR_)
                        .append(_FOUR_).append(_FOUR_).append("}").append(_BR_).append(_BR_);
                }
            }
            
            strb.append(_FOUR_).append(_FOUR_).append("form.submit();").append(_BR_);
            strb.append(_FOUR_).append("});").append(_BR_);
        }
        
        strb.append(Scripts.SCRIPT_TAIL_SUBMIT);
        
        //变灰和恢复两个函数
        strb.append(Scripts.setFormButtonGray());
        strb.append(Scripts.setFormButtonResume());
        
        //验证函数
        for (String function : functionMap.values())
        {
            strb.append(function);
        }
        
        if (strb.length() >= 4 && "\r\n\r\n".equals(strb.substring(strb.length() - 4)))
        {//去掉可能的最后是两个\r\n的一个\r\n
            strb.setLength(strb.length()-2);
        }
        
        strb.append(Scripts.tail());
        return strb.toString();
    }
    
    protected void destroy()
    {
        if (validateList != null)
        {
            validateList.clear();
            validateList = null;
        }
        
        confirm = null;
    }
}
